﻿using KinectWindowLib.NuiControls;
using KinectWindows.Math;
using SharpGL;
using SharpGL.SceneGraph;
using SharpGL.SceneGraph.Cameras;
using SharpGL.SceneGraph.Effects;
using SharpGL.SceneGraph.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KinectWindowLib.Graphics
{
    // This Sores all the OpenGL and VTK Attribute to render a full Drawables on the Screen Object
    public class GraphicContext
    {

        public Color Background { set; get; }
        


       

        /// <summary>
        /// Create the full GraphicContext
        /// </summary>
        /// <param name="screen">The Screen Object that the Context belong To</param>
        public void CreateGC()
        {
            Scene GL_Scene = new Scene();
            //  Create the 'Look At' camera
            var lookAtCamera = new LookAtCamera()
            {
                Position = new Vertex(0f, -10f, 0f),
                Target = new Vertex(0f, 0f, 0f),
                UpVector = new Vertex(0f, 0f, 1f)
            };

            //  Set the look at camera as the current camera.
            GL_Scene.CurrentCamera = lookAtCamera;
          //  GL_Scene.OpenGL.Viewport(0, 0,(int) Display.GetDefaultScreen().Width, (int)Display.GetDefaultScreen().Height);
            

            //  Create a set of scene attributes.
            OpenGLAttributesEffect sceneAttributes = new OpenGLAttributesEffect()
            {
                Name = "Scene Attributes"
            };

            //  Specify the scene attributes.
            sceneAttributes.EnableAttributes.EnableDepthTest = true;
            sceneAttributes.EnableAttributes.EnableNormalize = true;
            sceneAttributes.EnableAttributes.EnableLighting = true;
            sceneAttributes.EnableAttributes.EnableTexture2D = true;
            sceneAttributes.EnableAttributes.EnableBlend = true;
            // sceneAttributes.ColorBufferAttributes.BlendingSourceFactor = BlendingSourceFactor.SourceAlpha;
            // sceneAttributes.ColorBufferAttributes.BlendingDestinationFactor = BlendingDestinationFactor.OneMinusSourceAlpha;
            sceneAttributes.LightingAttributes.TwoSided = true;
            CreateGC(GL_Scene.OpenGL);
        }
        /// <summary>
        /// Distroy the Graphic Context
        /// </summary>
        public void DistroyGC() { }
        /// <summary>
        /// Refresh the Graphic Context by Redrawing 
        /// </summary>
        public void RefreshGC() { }



        public void ClearGC()
        {
            OpenGl.ClearColor(Background.R, Background.G, Background.B, Background.A);
        }

        /// <summary>
        /// Initalise The Grafic Context
        /// </summary>
        public void InitalizeGC()
        {
            Background = Color.Black;
        }
        public void CreateGC(OpenGL GL_Scene)
        {
            this.OpenGl = GL_Scene;          
            InitalizeGC();
        }
        public SharpGL.OpenGL OpenGl { get; set; }
        public SharpGL.SceneGraph.Scene GL_SCEN { get; set; }

        public void DrawPoint(Vector2 point)
        {
           
        }

        public void DrawLine(float x1, float y1, float x2, float y2)
        {
        }
        public void DrawRectangle(float X, float Y, float W, float H,Color Fill)
        {

            float x = MapScreenToWorld(X);
            float y = MapScreenToWorld(Y);
            float width = MapScreenToWorld(W);
            float height = MapScreenToWorld(H);
            

            OpenGl.LoadIdentity();
            OpenGl.Begin(OpenGL.GL_LINE_LOOP);

            OpenGl.Color(Fill.R, Fill.G, Fill.B);
            OpenGl.Vertex(x, y);
            OpenGl.Vertex(x + width, y);
            OpenGl.Vertex(x + width, y - height);
            OpenGl.Vertex(x, y - height);

            OpenGl.End();
            
        }
        public void DrawRectangle(Vector4 rec, Color Fill)
        {
        }
        public void FillRectangle(float X, float Y, float W, float H, Color Fill)
        {


            float x = MapScreenToWorld(X);
            float y = MapScreenToWorld(Y);
            float width = MapScreenToWorld(W);
            float height = MapScreenToWorld(H);
            OpenGl.LoadIdentity();
            OpenGl.Begin(OpenGL.GL_POLYGON);

            OpenGl.Color(Fill.R, Fill.G, Fill.B);
            OpenGl.Vertex(x, y);
            OpenGl.Vertex(x+width, y );
            OpenGl.Vertex(x+width, y-height);
            OpenGl.Vertex(x, y-height);

            OpenGl.End();
        }

        public float MapScreenToWorld(float X)
        {
            
            return X;
        }
        public void FillRectangle(Vector4 rec, Color Fill)
        {
        }
        public void DrawCircule(float x, float y, float rad)
        {
        }
        public void DrawCircule(float x, float y, float rad, float startAngle, float endAngle)
        {
        }
        public void DrawImage(Byte[] row, int width, int height)
        {
        }
        public void Clear(KinectWindows.Math.Vector2 vector21, KinectWindows.Math.Vector2 vector22)
        {           
        }
        public void Clear(KinectWindows.Math.Vector2 vector21, KinectWindows.Math.Vector2 vector22, Color Fill)
        {
        }
        public void DrawLine(Vector2 Start, Vector2 End, Color c)
        {
        }
        public void DrawPolyLine(Vector2 Start, Vector2[] lines, Color c)
        {
        }
        public void DrawRectangles(Vector4[] recs, Color Fill)
        {
        }
        public void FillRectangles(Vector4[] recs, Color[] Fill)
        {
        }
        public void DrawText(String txt, int size, Vector2 Location)
        {
        }
        public  Byte[] getSceneAsStream()
        {
            return null;
        }

        public void RefreshGC(int Width,int Height)
        {
            
           OpenGl.LoadIdentity();
           OpenGl.MatrixMode(OpenGL.GL_PROJECTION);
           OpenGl.LoadIdentity();
           OpenGl.Perspective(60, (double)Width / (double)Height, 0.1, 20);
           OpenGl.LookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);
           OpenGl.Viewport(0, Height, Width, -Height);
           OpenGl.MatrixMode(OpenGL.GL_MODELVIEW);
        }
    }

    /// <summary>
    /// Initalise The Display Canvas, Display class can use it
    /// </summary>
    public class NuiCanvas : NuiWidget
    {
        
       
        public NuiCanvas()
        {
            // TODO: Complete member initialization
           
        }
      
       
    }
}
